#include <YafridngRendererI.h>

YafridngRendererI::YafridngRendererI(const string& category,
				     const ::Ice::Int renderEngine,
				     const string& scene, 
				     Ice::CommunicatorPtr com) : 
  _category(category),
  _renderEngine(renderEngine),
  _scene(scene)
{
  try
    {
      _resultAdapter = com->createObjectAdapter("YafridngResultAdapter");
      _resultAdapter->activate();
    }
  catch(const AlreadyRegisteredException& ex)
    {
      cout << "catched Exception" << endl;
    }
}

void YafridngRendererI::obtainFile(const ::Yafridng::Pieces& piecesList,
				   ::Ice::Int piece,
				   ::Ice::Int fileSize,
				   const ::Yafridng::FilePrx& f,
				   const ::Yafridng::P2PBrokerPrx& broker,
				   const ::Ice::Current& c)
{
  createEmptyFile(_scene, fileSize);
  cout << "Writing file: " << _scene << endl;
  FileManager fm(_scene, f, "rb+", piecesList.at(piece).offset);
  fm.getFile();
  cout << "Obtained first piece" << endl;
  Yafridng::FileStorePrx file = FileStorePrx::uncheckedCast(_resultAdapter->addWithUUID(new FileStoreI(_category)));
  broker->notifyPiece(piece, file);
  cout << "Notifyed piece: " << piece << endl;

  for(int i = 0; i < piecesList.size(); i++){
    if(i != piece){
      Yafridng::FilePrx pieceFile = broker->getPieceKeeper(i/*, c.id.name*/);
      cout << "Obtained piece: " << i << endl;
      FileManager temp(_scene, pieceFile, "rb+", piecesList.at(i).offset);
      temp.getFile();
      cout << "Readed piece: " << i << endl;
    }
  }
}

void YafridngRendererI::render(const ::Yafridng::TZones& zones, 
			       const ::Yafridng::YafridngRenderManagerPrx& manager,
			       const ::Ice::Current& c)
{
  string path = "./temp/";
  string extension;
  int num = 1000 * 1024;
  int zone;
  
  Yafridng::FileStorePrx file = FileStorePrx::uncheckedCast(_resultAdapter->addWithUUID(new FileStoreI(_category)));
  while((zone = manager->queryZone(c.id.name)) != END){
    cout << "Valor devuelto por queryZone: " << zone << endl;
    switch(zone){
    case SLEEP:
      sleep(3);
      break;
    default:
      FILE* fp;
      int size;
      stringstream frame, x1, y1, x2, y2, suffix, band;
      string fileName;
      frame << zones.at(zone).frame;
      x1 << zones.at(zone).x1;
      y1 << zones.at(zone).y1;
      x2 << zones.at(zone).x2;
      y2 << zones.at(zone).y2;
      suffix << zones.at(zone).id;
      band << 10;
      
      fileName = _scene.substr(0, _scene.find(".", 0));
      fileName.append(suffix.str());
      
      string command = "blender -b " + _scene + " -P ./FinalRender.py -f " + frame.str() + " " + fileName + " " + 
	x1.str() + " " + y1.str() + " " + x2.str() + " " + y2.str() + " 1 " + band.str() + " 2";
      
      cout << command << endl;
      system(command.c_str());
      if(_renderEngine == 0)
	extension = "000" + frame.str() + ".png";
      else
	extension = "000" + frame.str();

      fileName.append(extension);
      manager->updateZone_async(new AMI_YafridngRenderManager_updateZoneI, 
				zone, 
				fileName, 
				file->read(path + fileName, num, 0, getFileSize(path + fileName)));
    }
  }
}

void YafridngRendererI::flush(const ::Ice::Current& c)
{
  cout << "Removing renderer" << endl;
  //system("./clean.sh");
  c.adapter->remove(c.id);
  _resultAdapter->destroy();
}

int YafridngRendererI::getFileSize(string file){
  FILE *fp;
  int size;
  if((fp = fopen(file.c_str(), "rb")) == NULL){
    cout << "Error Opening the file " << file << endl;
    exit(1);
  }
  fseek(fp, 0, SEEK_END);
  size = ftell(fp);
  fclose(fp);
  return size;
}

void YafridngRendererI::createEmptyFile(string name, int size){
  FILE *fp = fopen(name.c_str(), "wb");
  ByteSeq data(size);
  fwrite(&data[0], 1, size, fp);
  fclose(fp);
  cout << "Created empty file" << endl;
}
